// ChangeCloudFormat.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

int doWork(string filename, string out_filename) {
	string filetype = filename.substr(filename.size() - 3);
	if (filetype == "ply")
	{
		//ply 格式
		ifstream fin;
		fin.open(filename);
		string line;

		string file_fromat;
		int point_cnt = 0;
		getline(fin, line);
		while (line != "end_header")
		{
			if (line.find("format") != string::npos)
			{
				//第一个空格后
				file_fromat = line.substr(line.find(' '));//没有处理干净，不过判断足够了
			}
			if (line.find("element vertex") != string::npos) {
				point_cnt = stoi(line.substr(line.find_last_of(' ') + 1));
			}
			getline(fin, line);
		}
		if (file_fromat.find("ascii") == string::npos)
		{
			cout << "not ascii file ,failed" << endl;
			return -1;
		}

		//文本处理 不管有多少数据 直接读出来 然后取前三个当作xyz 保存
		ofstream fout;
		fout.open(out_filename);
		for (int i = 0; i < point_cnt; i++) {
			getline(fin, line);
			stringstream check1(line);
			string intermediate;
			for (int i = 0; i < 3; i++)
			{
				getline(check1, intermediate, ' ');
				fout << "   " << intermediate;
			}
			//没法输出LF 结尾 只能是LFCR 结尾…… \n 也不行
			fout << endl;
		}
		fin.close();
		fout.close();

	}
	else if (filetype == "obj") {
		//obj 格式
		//标准的obj 没有标注点数 完全靠读到最后
		//但是有的会以注释得形式给出…… 反正读到#开头就是注释不用管
		//v开头 看是vn 还是vt 还是v 只需要v
		//而且ascii 还是 binary 都没法判断
		//当作ascii 来读 如果有错误就报错！
		ifstream fin;
		fin.open(filename);
		string line;

		string file_fromat;
		int point_cnt = 0;
		while (line[0] != 'v')
		{
			if (line.find("Vertices") != string::npos) {
				auto pos_t = line.find_last_of(' ');
				if (pos_t == string::npos)
				{
					point_cnt = stoi(line.substr(line.find_last_of(' ') + 1));
				}
				else {
					//没有空格
					point_cnt = stoi(line.substr(line.find_last_of(':') + 1));
				}

			}
			getline(fin, line);
		}
		//如果注释有点信息
		if (point_cnt != 0)
		{
			int readed = 0;
			ofstream fout;
			fout.open(out_filename);
			while (readed < point_cnt && fin)
			{

				stringstream check1(line);
				string intermediate;
				getline(check1, intermediate, ' ');
				if (intermediate == "v")
				{
					//表示它真的是 点云
					readed++;
// 					getline(check1, intermediate, ' ');
// 					fout << intermediate;
					for (int i = 0; i < 3; i++)
					{
						getline(check1, intermediate, ' ');
						fout << "   " << intermediate;
					}
					//没法输出LF 结尾 只能是LFCR 结尾…… \n 也不行
					fout << endl;
				}
				//因为之前读取了v 开头的 所以要在最后getline
				getline(fin, line);
			}
			fin.close();
			fout.close();
		}
		else {
			//直接读取 直到读到不为v开头的
			ofstream fout;
			fout.open(out_filename);
			while (fin && line[0] == 'v')
			{
				stringstream check1(line);
				string intermediate;
				getline(check1, intermediate, ' ');
				if (intermediate == "v")
				{
					//表示它真的是 点云
					getline(check1, intermediate, ' ');
					fout << intermediate;
					for (int i = 0; i < 3; i++)
					{
						getline(check1, intermediate, ' ');
						fout << "   " << intermediate;
					}
					//没法输出LF 结尾 只能是LFCR 结尾…… \n 也不行
					fout << endl;
				}
				//因为之前读取了v 开头的 所以要在最后getline
				getline(fin, line);
			}
			fin.close();
			fout.close();
		}

		int t = 0;
	}
	else if (filetype == "pcd") {
		//pcd 格式 读到DATA 算是头结尾
		ifstream fin;
		fin.open(filename);
		string line;

		string file_fromat;
		int point_cnt = 0;
		while (line.find("DATA") == string::npos)
		{
			getline(fin, line);
			if (line.find("POINTS") != string::npos) {
				point_cnt = stoi(line.substr(line.find_last_of(' ') + 1));
			}
		}
		if (line.find("ascii") == string::npos)
		{
			cout << "not ascii file ,failed" << endl;
			return -1;
		}
		//文本处理 不管有多少数据 直接读出来 然后取前三个当作xyz 保存
		ofstream fout;
		fout.open(out_filename);
		//读出来就输入
		for (int i = 0; i < point_cnt; i++) {
			//没法直接拷贝 有长度限制
			// 			std::copy(
			// 				std::istreambuf_iterator<char>(fin),
			// 				std::istreambuf_iterator<char>(),
			// 				std::ostreambuf_iterator<char>(fout));
			getline(fin, line);
			fout << line << endl;
		}
		fin.close();
		fout.close();
	}
	else {
		//没有指定的格式
		cout << "file fromat not support" << endl;
	}
	return 0;
}
int main(int argc, char** argv)
{
    
	cout << "creat a txt file by input ascii pointcloud file" << endl;
	string filename = "t.pcd";
	string out_filename = "basic_xyz_ascii.txt";
	string todo_str = "todo.txt";
	//判断是否有此文件 ，有则进行批处理
	string line;
	ifstream fin(todo_str);
	if (fin) {
		
		while (getline(fin, line))
		{
			doWork(line+"head3d.obj", line+"basic_xyz_ascii.txt");
		}
		return 0;
	}

	switch (argc)
	{
	case 1:
		//直接运行的 需要指定文件名
		cin >> filename;
		break;
	case 2:
		//通过控制台运行 指定了文件名 直接运行
		filename = argv[1];
		break;
	case 3:
		//指定了输入和输入文件名
		filename = argv[1];
		out_filename = argv[2];
		break;
	default:
		break;
	}
	doWork(filename, out_filename);
	//string filename= "t.ply";
	//string filename = "t.obj";
	
	//cin >> filename;
	//list<array<float, 3>> points;//存放点云数据 或者读取了就不用存放
	//判断格式
	
	return 0;
}

